package ioc

import (
	"context"
	"gitee.com/DonHz/basic-go/webook/internal/web"
	ijwt "gitee.com/DonHz/basic-go/webook/internal/web/jwt"
	"gitee.com/DonHz/basic-go/webook/internal/web/middleware"
	"gitee.com/DonHz/basic-go/webook/pkg/ginx/middleware/logger"
	"gitee.com/DonHz/basic-go/webook/pkg/ginx/middleware/ratelimit"
	logger2 "gitee.com/DonHz/basic-go/webook/pkg/logger"
	"github.com/fsnotify/fsnotify"
	"github.com/gin-contrib/cors"
	"github.com/gin-contrib/sessions"
	session_redis "github.com/gin-contrib/sessions/redis"
	"github.com/gin-gonic/gin"
	"github.com/redis/go-redis/v9"
	"github.com/spf13/viper"
	"strings"
	"time"
)

func InitWebServer(mdl []gin.HandlerFunc, hdl *web.UserHandler,
	oauth2WechatHdl *web.OAuth2WechatHandler, articleHdl *web.ArticleHandler) *gin.Engine{
	r:=gin.Default()
	r.Use(mdl...)
	hdl.RegisterRoutes(r)
	articleHdl.RegisterRoutes(r)
	oauth2WechatHdl.RegisterRoutes(r)
	return r
}

func InitMiddlewares(redisClient redis.Cmdable, handler ijwt.Handler, l logger2.Logger) []gin.HandlerFunc {
	bd:=logger.NewMiddlewareLoggerBuilder(func(ctx context.Context, al *logger.AccessLog){
		l.Debug("HTTP请求", logger2.Field{Key: "AccessLog", Value: al})
	}, l).AllowRespBody(true).AllowReqBody(true)
	viper.OnConfigChange(func(in fsnotify.Event) {
		ok:=viper.GetBool("web.logreq")
		bd.AllowRespBody(ok)
	})
	return []gin.HandlerFunc{
		bd.Build(),
		corsHdl(),
		ignorePathHdl(handler),
		ratelimit.NewBuilder(InitRateLimit(redisClient)).Build(),
		sessionsHdl(),
	}
}

func corsHdl() gin.HandlerFunc{
	// 解决前后端分离的跨域问题
	return cors.New(cors.Config{
		// AllowOrigins: []string{"https://localhost:3000"},
		AllowMethods: []string{"PUT"},
		AllowHeaders: []string{"Content-Type", "Authorization"},
		// 不加这个，前端拿不到
		ExposeHeaders: []string{"x-jwt-token", "x-refresh-token"},
		// 是否允许带 cookie 之类的东西
		AllowCredentials: true,
		AllowOriginFunc: func(origin string) bool {
			if strings.HasPrefix(origin, "http://localhost") {
				return true
			}
			return strings.Contains(origin, "yourcompany.com")
		},
		MaxAge: 12 * time.Hour,
	})
}

func ignorePathHdl(handler ijwt.Handler) gin.HandlerFunc{
	return middleware.NewLoginJWTMiddlewareBuilder(handler).
		IgnorePaths("/users/login").
		IgnorePaths("/users/refresh_token").
		IgnorePaths("/users/login_sms").
		IgnorePaths("/users/login_sms/code/send").
		IgnorePaths("/oauth2/wechat/authurl").
		IgnorePaths("/users/signup").Build()
}

func sessionsHdl() gin.HandlerFunc {
	// 步骤1
	//store := cookie.NewStore([]byte("secret"))
	// 可在网页上搜索 生成随机密钥
	//store := memstore.NewStore([]byte("32位或64位的authentication key"), []byte("encryption key"))
	// 使用 gin redis session Store
	store, err := session_redis.NewStore(16, "tcp", "localhost:6379", "",
		// 身份认证 key
		[]byte("qJfZR1psrw3PXpT1aPbeRoUl0eLtdBH2bcFobbf9MKhdbd8MoR2V046H0obQd2tc"),
		// 数据加密 key
		[]byte("YRUjPBZzysaoAxAx31f5pXMwithO9AR2FX6ZspHzSKbtLkH2JcIf6PyeQwQyR4bS"))
	if err != nil {
		println(err)
	}
	return sessions.Sessions("mysession", store)
}
